﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using Findy.XsltDb;
using System;
using System.Web;
using System.Security;
using System.Text;
using System.Threading;
using System.IO;
using System.Xml.XPath;
using DotNetNuke.Entities.Users;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;

namespace Findy.XsltDb.Handlers
{

    public class WsBase : IHttpHandler, IXsltDbService
    {

        public void ProcessRequest(HttpContext context)
        {
            XsltDbUtils.UpdateCulture();

            string encoding = (context.Request["encoding"] ?? string.Empty).Trim();
            Encoding enc = Encoding.UTF8;
            try
            {
                if (encoding.Length != 0)
                {
                    int codepage;
                    if (int.TryParse(encoding, out codepage))
                        enc = Encoding.GetEncoding(codepage);
                    else
                        enc = Encoding.GetEncoding(encoding);
                }
            }
            catch(Exception ex) {
                XsltDbUtils.WriteLog(ex);
            }

            context.Response.ContentEncoding = enc;

            string res = string.Empty;
            try
            {
                res = Execute(context);
            }
            catch (SecurityException) { throw; }
            catch (Exception ex)
            {
                if (ex.InnerException is Findy.XsltDb.RedirectException)
                {
                    RedirectException rex = ex.InnerException as RedirectException;
                    if (rex != null)
                    {
                        if (rex.IsTransfer)
                            context.Server.TransferRequest(rex.URL, true);
                        else
                            context.Response.Redirect(rex.URL, false);
                        return;
                    }
                }
                UserInfo currentUser = UserController.GetCurrentUserInfo();
                if (currentUser.IsInRole("Administrators") || currentUser.IsSuperUser)
                    res = Findy.XsltDb.XsltDbUtils.GetExceptionMessage(ex);
                XsltDbUtils.WriteLog(ex);
            }
            res = res.Trim();
            if (res.Length > 0)
                context.Response.Write(res);
            //Response.Cookies.Add(new HttpCookie("language", System.Threading.Thread.CurrentThread.CurrentCulture.ToString()));
        }

        private string Execute(HttpContext context)
        {
            string serviceName = (context.Request["service"] ?? string.Empty).Trim();
            string ConfigID = (context.Request["config"] ?? string.Empty).ToLower().Trim();
            int mod = int.Parse(context.Request["mod"] ?? "-1");
            int TabID = int.Parse(context.Request["tabid"] ?? "-1");
            int TabModuleID = int.Parse(context.Request["tmid"] ?? "-1");
            string xsl = null;
            int ModuleID = -1;
            bool IsSuper = false;
            bool useMdoService = false;
            XsltDbUtils.aConfig c = null;

            if (ConfigID.Length > 0)
            {
                c = XsltDbUtils.GetConfigByID(ConfigID);
                xsl = c.ActiveXslt;
                IsSuper = c.IsSuper;
                useMdoService = true;
                ModuleID = mod;
            }
            else
            {
                if (mod > 0 && serviceName.Length > 0)
                {
                    ModuleID = mod;
                    c = XsltDbUtils.GetConfig(ModuleID, TabID > 0 ? TabID : Null.NullInteger);
                    xsl = c.ActiveXslt;
                    IsSuper = c.IsSuper;
                    useMdoService = true;
                }

                if (ModuleID == -1)
                {
                    if (!string.IsNullOrEmpty(serviceName))
                    {
                        c = XsltDbUtils.GetConfigByService(serviceName);
                        if (c != null)
                        {
                            TabID = c.TabID;
                            ModuleID = c.ModuleID;
                            TabModuleID = c.TabModuleID;
                            xsl = c.ActiveXslt;
                            IsSuper = c.IsSuper;
                        }
                    }

                    if (ModuleID == -1)
                    {
                        ModuleID = mod;
                        c = XsltDbUtils.GetConfig(ModuleID, TabID > 0 ? TabID : Null.NullInteger);
                        xsl = c.ActiveXslt;
                        IsSuper = c.IsSuper;
                    }

                }
            }
            var t = new Transformer(TabModuleID, ModuleID, TabID);
            t.Config = c;

            string xml = "<root/>";
            try
            {
                var tXml = new StreamReader(context.Request.InputStream).ReadToEnd().Trim();
                if (tXml.Length > 0 && tXml[0] == '<')
                {
                    context.Request.InputStream.Seek(0, SeekOrigin.Begin);
                    xml = new XPathDocument(context.Request.InputStream).CreateNavigator().OuterXml;
                }
            }
            catch (Exception) { }

            string res = string.Empty;
            if (xsl.Trim().Length > 0)
            {
                if (useMdoService)
                {
                    //[Response.ContentType] is set inside ExecuteService
                    res = t.ExecuteService(xsl, xml, serviceName, IsSuper, TabID).Trim();

                }
                else
                {
                    context.Response.ContentType = context.Request.Params["content-type"] ?? "text/xml";
                    res = t.Transform(xml, xsl, IsSuper).Trim();
                }
            }
            return res;
        }


        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

    }
}